package com.zwps.biz.domain.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zwps.biz.api.model.dto.broadcast.BroadcastDTO;
import com.zwps.biz.api.model.dto.broadcast.SBroadcastDTO;
import com.zwps.common.cache.CacheService;
import okhttp3.*;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class ApiService {
    private static final Logger log = LoggerFactory.getLogger(ApiService.class);
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Value(value = "${application.broadcast.url}")
    private String baseUrl;
    @Value(value = "${application.broadcast.authHeader}")
    private String authHeader;

    @Value("${application.auth.forecast-host}")
    String forecastHost;
    @Value("${application.auth.projectId}")
    String projectId;

//    private Integer roomNum;
    @Autowired
    private OkHttpClient okHttpClient;
    @Autowired
    private CacheService cacheService;


    public void savDeviceId() {
        String oneRoom = fetchDataByGet("device", 1);
        String towRoom = fetchDataByGet("device", 2);
        cacheDeviceId(oneRoom, 1);
        cacheDeviceId(towRoom, 2);
    }

    private void cacheDeviceId(String oneRoom, Integer num) {
        JSONObject jsonObject = JSONObject.parseObject(oneRoom);
        JSONArray jsonArray = jsonObject.getJSONArray("data");
        for (int i = 0; i < jsonArray.size(); i++) {
            try {
                JSONObject device = jsonArray.getJSONObject(i);
                String id = device.getString("id");
                String deviceCode = device.getString("code");

                if (id == null) id = "";
                if (deviceCode == null) deviceCode = "";

                String concatenated = id + "_" + deviceCode;

                // 推荐方式：设置 30 天过期
                stringRedisTemplate.opsForValue().set(
                        concatenated,
                        num.toString(),
                        Duration.ofDays(30)
                );

            } catch (Exception e) {
                throw new RuntimeException("缓存设备ID失败: " + e.getMessage(), e);
            }
        }
    }

    public String fetchDataByGet(String path,Integer roomNum) {
        Request request = new Request.Builder()
                .url(baseUrl+"broadcastRoom"+roomNum+"/v1/" + path)
                .header("Authorization", authHeader)
                .get()
                .build();
        return executeRequest(request);
    }

    // 新增 POST 请求方法
    public String fetchDataByPost(String path, String jsonBody,Integer roomNum) {
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(jsonBody, JSON);

        Request request = new Request.Builder()
                .url(baseUrl +"broadcastRoom"+roomNum+"/v1/"+ path)
                .header("Authorization", authHeader)
                .post(body)
                .build();
        return executeRequest(request);
    }
    // 新增 POST 请求方法
    public String wcpByPost(String path, String jsonBody) {
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(jsonBody, JSON);

        Request request = new Request.Builder()
                .url(forecastHost + path)
                .header("projectId", projectId)
                .post(body)
                .build();
        return executeRequest(request);
    }

    // 新增 POST 请求方法
    public String fetchDataByPatch(String path, String jsonBody) {
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(jsonBody, JSON);

        Request request = new Request.Builder()
                .url(baseUrl + path)
                .header("Authorization", authHeader)
                .patch(body)
                .build();
        return executeRequest(request);
    }

    // 提取公共请求执行逻辑
    private String executeRequest(Request request) {
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful() || response.body() == null) {
                throw new RuntimeException("请求失败，状态码: " + response.code()+response.message());
            }
            return response.body().string();
        } catch (Exception e) {
            throw new RuntimeException("API请求异常: " + e.getMessage());
        }
    }

    public JSONObject getDevice() {
        JSONObject json1 = null;
        JSONObject json2 = null;
        Exception error1 = null;
        Exception error2 = null;

        try {
            // 获取第一页数据
            String response1 = fetchDataByGet("device", 1);
            json1 = JSONObject.parseObject(response1);
        } catch (Exception e) {
            error1 = e;
            System.err.println("获取第一页数据时出错: " + e.getMessage());
        }

        try {
            // 获取第二页数据
            String response2 = fetchDataByGet("device", 2);
            json2 = JSONObject.parseObject(response2);
        } catch (Exception e) {
            error2 = e;
            System.err.println("获取第二页数据时出错: " + e.getMessage());
        }

        // 如果两个请求都失败
        if (json1 == null && json2 == null) {
            JSONObject errorResult = new JSONObject();
            errorResult.put("code", 500);
            errorResult.put("message", "所有数据获取失败: " +
                    (error1 != null ? error1.getMessage() : "") +
                    (error2 != null ? "; " + error2.getMessage() : ""));
            errorResult.put("data", new JSONArray());
            return errorResult;
        }

        // 创建合并后的结果对象
        JSONObject mergedResult = new JSONObject();
        mergedResult.put("code", 200);

        // 合并data数组
        JSONArray mergedData = new JSONArray();
        int totalCount = 0;
        int total = 0;
        int pageCount = 0;

        // 处理第一页数据
        if (json1 != null && json1.containsKey("data") && json1.get("data") instanceof JSONArray) {
            JSONArray data1 = json1.getJSONArray("data");
            mergedData.addAll(data1);
            totalCount += getIntValue(json1, "count");
            total = getIntValue(json1, "total");
            pageCount = getIntValue(json1, "page_count");

            // 缓存处理
            if (cacheService.getValue(getIdCOde(data1)) == null) {
                savDeviceId();
            }
        }

        // 处理第二页数据
        if (json2 != null && json2.containsKey("data") && json2.get("data") instanceof JSONArray) {
            JSONArray data2 = json2.getJSONArray("data");
            mergedData.addAll(data2);
            totalCount += getIntValue(json2, "count");

            // 如果第一页失败，使用第二页的total和page_count
            if (json1 == null) {
                total = getIntValue(json2, "total");
                pageCount = getIntValue(json2, "page_count");
            }

            // 缓存处理
            if (cacheService.getValue(getIdCOde(data2)) == null) {
                savDeviceId();
            }
        }

        // 设置结果
        mergedResult.put("message", "数据合并成功" +
                (error1 != null ? " (room1获取失败)" : "") +
                (error2 != null ? " (room2获取失败)" : ""));
        mergedResult.put("count", totalCount);
        mergedResult.put("total", total);
        mergedResult.put("page", 1); // 合并后视为第一页
        mergedResult.put("page_count", pageCount);
        mergedResult.put("data", mergedData);

        return mergedResult;

    }
    public String getIdCOde(JSONArray jsonArray){
        String id = jsonArray.getJSONObject(0).getString("id");
        String code = jsonArray.getJSONObject(0).getString("code");
        id=id+"_"+code;
        return  id;
    }
    private int getIntValue(JSONObject json, String key) {
        return json.containsKey(key) ? json.getIntValue(key) : 0;
    }

    public JSONObject getPlan(String deviceId) {
        return JSONObject.parseObject(fetchDataByGet("plan",Integer.parseInt(stringRedisTemplate.opsForValue().get(deviceId))));
    }

    public JSONObject getFile(String deviceId) {
        return JSONObject.parseObject(fetchDataByGet("file",Integer.parseInt(stringRedisTemplate.opsForValue().get(deviceId))));
    }

    public String addTask(BroadcastDTO dto) {
        return fetchDataByPost("task", dto.toString(),null);
    }

    public String addTask(String path, Object dto) {
        String jsonBody = convertDtoToJson(dto); // DTO转JSON
        return fetchDataByPost(path, jsonBody,null);
    }

    private String convertDtoToJson(Object dto) {
        try {
            return new ObjectMapper().writeValueAsString(dto); // 使用Jackson
        } catch (JsonProcessingException e) {
            throw new RuntimeException("DTO转换JSON失败: " + e.getMessage());
        }
    }

    public String startTask(String id) {
        if (id != null && id.contains("_")) {
            int underscoreIndex = id.indexOf("_");
            id = id.substring(0, underscoreIndex);
        }
        String path = "task/" + id + "/start";
        return fetchDataByGet(path,Integer.parseInt(id));
    }

    public String stopTask(String id) {
        if (id != null && id.contains("_")) {
            int underscoreIndex = id.indexOf("_");
            id = id.substring(0, underscoreIndex);
        }
        String path = "task/" + id + "/stop";
        return fetchDataByGet(path,Integer.parseInt(stringRedisTemplate.opsForValue().get(id)));
    }

    public String updateTask(String realTimeTask, SBroadcastDTO dto,Integer num) {

        String jsonBody = convertDtoToJson(dto); // DTO转JSON
//        String s = fetchDataByPatch(realTimeTask, jsonBody);
        return fetchDataByPost(realTimeTask + "/start", jsonBody,num);
    }

    public String stopSTask(String id) {
        return fetchDataByGet("real_time_task/stop",Integer.parseInt(cacheService.getValue(id)));
    }
}
